home *** CD-ROM | disk | FTP | other *** search
/ Visual Cafe 3 / Visual Cafe 3.ISO / Vcafe / JFC.bin / OrganicSliderUI.java < prev    next >
Text File  |  1998-06-30  |  14KB  |  435 lines

  1. /*
  2.  * @(#)OrganicSliderUI.java    1.5 98/02/02
  3.  * 
  4.  * Copyright (c) 1997 Sun Microsystems, Inc. All Rights Reserved.
  5.  * 
  6.  * This software is the confidential and proprietary information of Sun
  7.  * Microsystems, Inc. ("Confidential Information").  You shall not
  8.  * disclose such Confidential Information and shall use it only in
  9.  * accordance with the terms of the license agreement you entered into
  10.  * with Sun.
  11.  * 
  12.  * SUN MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF THE
  13.  * SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
  14.  * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
  15.  * PURPOSE, OR NON-INFRINGEMENT. SUN SHALL NOT BE LIABLE FOR ANY DAMAGES
  16.  * SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR DISTRIBUTING
  17.  * THIS SOFTWARE OR ITS DERIVATIVES.
  18.  * 
  19.  */
  20.  
  21. package com.sun.java.swing.plaf.organic;
  22.  
  23. import com.sun.java.swing.plaf.basic.BasicSliderUI;
  24.  
  25. import java.awt.Component;
  26. import java.awt.Container;
  27. import java.awt.Graphics;
  28. import java.awt.Dimension;
  29. import java.awt.Rectangle;
  30. import java.awt.Point;
  31. import java.awt.Insets;
  32. import java.awt.Color;
  33. import java.io.Serializable;
  34. import java.awt.IllegalComponentStateException;
  35. import java.awt.Polygon;
  36. import java.beans.*;
  37.  
  38. import com.sun.java.swing.border.AbstractBorder;
  39.  
  40. import com.sun.java.swing.*;
  41. import com.sun.java.swing.event.*;
  42. import com.sun.java.swing.plaf.*;
  43.  
  44. /**
  45.  * A Java L&F implementation of SliderUI.  
  46.  * <p>
  47.  * Warning: serialized objects of this class will not be compatible with
  48.  * future swing releases.  The current serialization support is appropriate
  49.  * for short term storage or RMI between Swing1.0 applications.  It will
  50.  * not be possible to load serialized Swing1.0 objects with future releases
  51.  * of Swing.  The JDK1.2 release of Swing will be the compatibility
  52.  * baseline for the serialized form of Swing objects.
  53.  *
  54.  * @version 1.5 02/02/98
  55.  * @author Tom Santos
  56.  */
  57. public class OrganicSliderUI extends BasicSliderUI implements PropertyChangeListener {
  58.   
  59.     protected boolean filledSlider = false;
  60.     protected static Color thumbColor;
  61.     protected static Color highlightColor;
  62.     protected static Color darkShadowColor;
  63.  
  64.  
  65.     protected final String SLIDER_FILL = "JSlider.isFilled";
  66.  
  67.     public static ComponentUI createUI(JComponent c)    {
  68.         return new OrganicSliderUI();
  69.     }
  70.  
  71.     public OrganicSliderUI() {
  72.         super( null );
  73.     }
  74.  
  75.     public void installUI( JComponent c ) {
  76.         super.installUI( c );
  77.  
  78.     thumbColor = UIManager.getColor("Slider.thumb");
  79.     highlightColor = UIManager.getColor("Slider.highlight");
  80.     darkShadowColor = UIManager.getColor("Slider.darkShadow");
  81.  
  82.     scrollListener.setScrollByBlock( false );
  83.  
  84.     c.addPropertyChangeListener( this ); // add to listen for filled slider change
  85.  
  86.     Object sliderFillProp = c.getClientProperty( SLIDER_FILL );
  87.     if ( sliderFillProp != null ) {
  88.         filledSlider = ((Boolean)sliderFillProp).booleanValue();
  89.     }
  90.     }
  91.  
  92.     public void uninstallUI( JComponent c ) {
  93.      c.removePropertyChangeListener( this );
  94.     super.uninstallUI( c );
  95.     }
  96.  
  97.     public void propertyChange( PropertyChangeEvent e ) {  // listen for slider fill
  98.         super.propertyChange( e );
  99.  
  100.     String name = e.getPropertyName();
  101.     if ( name.equals( SLIDER_FILL ) ) {
  102.         if ( e.getNewValue() != null ) {
  103.             filledSlider = ((Boolean)e.getNewValue()).booleanValue();
  104.         }
  105.         else {
  106.         filledSlider = false;
  107.         }
  108.         }
  109.     }
  110.  
  111.     public void paintThumb(Graphics g)  {
  112.  
  113.     Rectangle knobBounds = getThumbRect();
  114.         g.translate( knobBounds.x, knobBounds.y );
  115.  
  116.     Color triangleColor;
  117.     Color ditherColor1;
  118.     Color ditherColor2;
  119.  
  120.     if ( slider.isEnabled() ) {
  121.         triangleColor = thumbColor;
  122.         ditherColor1 = darkShadowColor;
  123.         ditherColor2 = slider.getForeground();
  124.     }
  125.     else {
  126.         triangleColor = slider.getForeground();
  127.         ditherColor1 = slider.getForeground();
  128.         ditherColor2 = slider.getBackground();
  129.     }
  130.  
  131.         boolean isVertical = slider.getOrientation() == JSlider.VERTICAL;
  132.  
  133.     // Draw triangle
  134.         g.setColor( triangleColor );
  135.     drawLine( g, knobBounds.width, 0, 0, 14, 0, isVertical );
  136.     fillRect( g, knobBounds.width, 1, 1, 13, 2, isVertical );
  137.     fillRect( g, knobBounds.width, 2, 3, 11, 2, isVertical );
  138.     fillRect( g, knobBounds.width, 3, 5, 9, 2, isVertical );
  139.     fillRect( g, knobBounds.width, 4, 7, 7, 2, isVertical );
  140.     fillRect( g, knobBounds.width, 5, 9, 5, 2, isVertical );
  141.     fillRect( g, knobBounds.width, 6, 11, 3, 2, isVertical );
  142.     drawLine( g, knobBounds.width, 7, 13, 7, 14, isVertical );
  143.  
  144.     // Draw dither
  145.     g.setColor( ditherColor1 );
  146.     drawLine( g, knobBounds.width, 0, 1, 0, 1, isVertical );
  147.     drawLine( g, knobBounds.width, 14, 1, 14, 1, isVertical );
  148.     drawLine( g, knobBounds.width, 1, 3, 1, 4, isVertical );
  149.     drawLine( g, knobBounds.width, 13, 3, 13, 4, isVertical );
  150.     drawLine( g, knobBounds.width, 2, 5, 2, 6, isVertical );
  151.     drawLine( g, knobBounds.width, 12, 5, 12, 6, isVertical );
  152.     drawLine( g, knobBounds.width, 3, 7, 3, 8, isVertical );
  153.     drawLine( g, knobBounds.width, 11, 7, 11, 8, isVertical );
  154.     drawLine( g, knobBounds.width, 4, 9, 4, 9, isVertical );
  155.     drawLine( g, knobBounds.width, 10, 9, 10, 9, isVertical );
  156.     drawLine( g, knobBounds.width, 5, 11, 5, 11, isVertical );
  157.     drawLine( g, knobBounds.width, 9, 11, 9, 11, isVertical );
  158.     drawLine( g, knobBounds.width, 6, 13, 6, 13, isVertical );
  159.     drawLine( g, knobBounds.width, 8, 13, 8, 13, isVertical );
  160.  
  161.     if ( slider.isEnabled() ) {
  162.       g.setColor( ditherColor2 );
  163.       drawLine( g, knobBounds.width, 0, 2, 0, 2, isVertical );
  164.       drawLine( g, knobBounds.width, 14, 2, 14, 2, isVertical );
  165.       drawLine( g, knobBounds.width, 4, 10, 4, 10, isVertical );
  166.       drawLine( g, knobBounds.width, 10, 10, 10, 10, isVertical );
  167.       drawLine( g, knobBounds.width, 5, 12, 5, 12, isVertical );
  168.       drawLine( g, knobBounds.width, 9, 12, 9, 12, isVertical );
  169.     }
  170.  
  171.     g.translate( -knobBounds.x, -knobBounds.y );
  172.     }
  173.  
  174.     protected void drawLine( Graphics g, int knobWidth,
  175.                  int origX1, int origY1,
  176.                  int origX2, int origY2,
  177.                  boolean vertical ) {
  178.         int x1 = origX1;
  179.     int y1 = origY1;
  180.     int x2 = origX2;
  181.     int y2 = origY2;
  182.  
  183.     // Rotate the line 90 degrees counterclockwise around the center
  184.         if ( vertical ) {
  185.         x1 = origY1;
  186.         y1 = knobWidth - origX1;
  187.         x2 = origY2;
  188.         y2 = knobWidth - origX2;
  189.     }
  190.  
  191.     g.drawLine( x1, y1, x2, y2 );
  192.     }
  193.  
  194.     protected void fillRect( Graphics g, int knobWidth,
  195.                  int origX, int origY,
  196.                  int origWidth, int origHeight,
  197.                  boolean vertical ) {
  198.         int x = origX;
  199.     int y = origY;
  200.     int width = origWidth;
  201.     int height = origHeight;
  202.  
  203.     // Rotate the rect 90 degrees counterclockwise
  204.     if ( vertical ) {
  205.         x = origY;
  206.         y = (knobWidth - origX) - origWidth;
  207.         width = origHeight;
  208.         height = origWidth + 1; // I have no idea why I had to add 1 here. -tjs-
  209.     }
  210.  
  211.     g.fillRect( x, y, width, height );
  212.     }
  213.  
  214.     public void paintTrack(Graphics g)  {
  215.     
  216.     Rectangle trackBounds = getScrollTrackRect();
  217.  
  218.     // Draw Background
  219. /*    if ( slider.isOpaque() ) {
  220.         g.setColor(slider.getBackground());
  221.         g.fillRect(trackBounds.x, trackBounds.y, trackBounds.width, trackBounds.height);
  222.     }*/
  223.  
  224.     boolean drawTrackBackground = slider.isEnabled();
  225.  
  226.     Color trackColor = slider.getForeground();
  227.     Color endcapColor;
  228.     Color backboneColor;
  229.  
  230.     if ( slider.isEnabled() ) {
  231.         endcapColor = OrganicLookAndFeel.getBlack();
  232.         backboneColor = darkShadowColor;
  233.     }
  234.     else {
  235.         trackColor = slider.getForeground();
  236.         endcapColor = darkShadowColor;
  237.         backboneColor = slider.getForeground();
  238.     }
  239.  
  240.     g.translate( trackBounds.x, trackBounds.y );
  241.  
  242.     if( slider.getOrientation() == JSlider.HORIZONTAL ) {
  243.         int trackTop = (trackBounds.height - getTrackWidth()) - getThumbOverhang();
  244.         int trackLeft = trackBuffer;
  245.         int trackRight = (trackBounds.width - 1) - trackBuffer;
  246.         
  247.         // Draw track background
  248.         g.setColor( trackColor );
  249.  
  250.         if ( drawTrackBackground ) {
  251.         g.fillRect( trackLeft, trackTop, getTrackLength(), getTrackWidth() );
  252.         }
  253.         else {
  254.             g.drawLine( trackLeft, trackTop + getTrackWidth() - 1,
  255.                 trackRight - 2, trackTop + getTrackWidth() - 1 );
  256.         }
  257.         
  258.         // Draw backbone
  259.         g.setColor( backboneColor );
  260.         g.drawLine( trackLeft, trackTop, trackRight, trackTop );
  261.         
  262.         // Draw end-caps
  263.         g.setColor( endcapColor );
  264.         g.fillRect( trackLeft, trackTop, 2, getTrackWidth() );
  265.         g.fillRect( trackRight, trackTop, 2, getTrackWidth() );
  266.  
  267.         // Draw fill
  268.         if ( filledSlider ) {
  269.             Rectangle thumbBounds = getThumbRect();
  270.         int middleOfThumb = thumbBounds.x + (thumbBounds.width / 2);
  271.  
  272.         g.setColor( OrganicLookAndFeel.getBlack() );
  273.  
  274.             if ( !slider.getInverted() ) {
  275.             int fillLength = middleOfThumb - trackLeft;
  276.             for ( int xPos = trackLeft; xPos < middleOfThumb; xPos += 3 ) {
  277.                 g.fillRect( xPos, trackTop+1, 2, getTrackWidth()-1 );
  278.             }
  279.         }
  280.         else {
  281.             int fillLength = trackRight - middleOfThumb;
  282.             for ( int xPos = trackRight; xPos > middleOfThumb; xPos -= 3 ) {
  283.                 g.fillRect( xPos, trackTop+1, 2, getTrackWidth()-1 );
  284.             }
  285.         }
  286.         }
  287.     }
  288.     else {  // Vertical slider
  289.         int trackLeft = (trackBounds.width - getTrackWidth()) - getThumbOverhang();
  290.         int trackTop = trackBuffer;
  291.         int trackBottom = trackTop + (getTrackLength() - 1);
  292.         int trackRight = trackLeft + getTrackWidth() - 1;
  293.         
  294.         // Draw track background
  295.         g.setColor( trackColor );
  296.  
  297.         if ( drawTrackBackground ) {
  298.             g.fillRect( trackLeft, trackTop, getTrackWidth(), getTrackLength() );
  299.         }
  300.         else {
  301.             g.drawLine( trackRight, trackTop, trackRight, trackBottom );
  302.         }
  303.         
  304.         // Draw backbone
  305.         g.setColor( backboneColor );
  306.         g.drawLine( trackLeft, trackTop + 2, trackLeft, trackBottom);
  307.         
  308.         // Draw end-caps
  309.         g.setColor( endcapColor );
  310.         g.fillRect( trackLeft, trackTop, getTrackWidth(), 2 );
  311.         g.fillRect( trackLeft, trackBottom, getTrackWidth(), 2 );
  312.  
  313.         // Draw fill
  314.         if ( filledSlider ) {
  315.             Rectangle thumbBounds = getThumbRect();
  316.         int middleOfThumb = thumbBounds.y + (thumbBounds.height / 2);
  317.         g.setColor( OrganicLookAndFeel.getBlack() );
  318.  
  319.             if ( !slider.getInverted() ) {
  320.             int fillLength = trackBottom - middleOfThumb;
  321.             for ( int yPos = trackBottom; yPos > middleOfThumb; yPos -= 3 ) {
  322.                 g.fillRect( trackLeft+1, yPos, getTrackWidth()-1, 2 );
  323.             }
  324.         }
  325.         else {
  326.             int fillLength = trackBottom - middleOfThumb;
  327.             for ( int yPos = trackTop; yPos < middleOfThumb; yPos += 3 ) {
  328.                 g.fillRect( trackLeft+1, yPos, getTrackWidth()-1, 2 );
  329.             }
  330.         }
  331.         }
  332.     }
  333.  
  334.     g.translate( -trackBounds.x, -trackBounds.y );
  335.     }
  336.  
  337.     public void paintFocus(Graphics g)  {
  338.         if (slider.hasFocus()) {
  339.         /// PENDING(klobad) copied from Button code - fix when 2D available
  340.             // Draw each dash of the line pixel by pixel.
  341.             // The performance of this is surely poor -- Be sure
  342.             // to rewrite when 2d graphics package is ready.
  343.         Rectangle r = slider.getBounds();
  344.         r.x = 0;
  345.             r.y = 0;        
  346.         if(slider.getBorder() != null) {
  347.              r = getFullContentArea();
  348.         } 
  349.             g.setColor(highlightColor);
  350.             g.drawRect(r.x + 1, r.y + 1, r.width - 3, r.height - 3);
  351.  
  352.         super.paintFocus( g );
  353.         }
  354.     }
  355.  
  356.     /**
  357.       * Subclasses of BasicSliderUI override this method to determine their own
  358.       * thumb size.
  359.       */
  360.     public void calculateThumbBounds()    {
  361.         if ( slider.getOrientation() == JSlider.HORIZONTAL ) {
  362.         int thumbX = xPositionForValue( slider.getValue( )) - getThumbRect().width / 2;
  363.         int thumbY = (getScrollTrackRect().y + getScrollTrackRect().height) - 16;
  364.  
  365.         setThumbBounds( thumbX, thumbY, 15, 15 );
  366.         }
  367.     else {
  368.         int thumbY = yPositionForValue(slider.getValue()) - getThumbRect().height / 2;
  369.         int thumbX = (getScrollTrackRect().x + getScrollTrackRect().width) - 16;
  370.  
  371.         setThumbBounds( thumbX, thumbY, 15, 16 );
  372.     }
  373.     }
  374.  
  375.     /**
  376.      * Gets the height of the tick area for horizontal sliders and the width of the
  377.      * tick area for vertical sliders.  BasicSliderUI uses the returned value to
  378.      * determine the bounds of the tray rectangle and the tick area rectangle.
  379.      */
  380.     public int getTickSize() {
  381.         return 5;
  382.     }
  383.  
  384.     /**
  385.      * Returns the shorter dimension of the track.
  386.      */
  387.     protected int getTrackWidth() {
  388.         return 7;
  389.     }
  390.  
  391.     /**
  392.      * Returns the longer dimension of the slide bar.  (The slide bar is only the
  393.      * part that runs directly under the thumb)
  394.      */
  395.     protected int getTrackLength() {   
  396.     Rectangle interiorRect = getFullContentArea();
  397.  
  398.     if ( slider.getOrientation() == JSlider.HORIZONTAL ) {
  399.         return getScrollTrackRect().width - (trackBuffer * 2);
  400.     }
  401.     return getScrollTrackRect().height - (trackBuffer * 2);
  402.     }
  403.  
  404.     /**
  405.      * Returns the amount that the thumb goes past the slide bar.
  406.      */
  407.     protected int getThumbOverhang() {
  408.         return 5;
  409.     }
  410.  
  411.     protected void scrollDueToClickInTrack( int dir ) {
  412.         scrollByUnit( dir );
  413.     }
  414.  
  415.     protected void paintMinorTickForHorizSlider( Graphics g, Rectangle tickBounds, int x ) {
  416.     g.setColor( slider.getForeground() );
  417.     g.fillRect( x, 0 , 2, 2 );
  418.     }
  419.  
  420.     protected void paintMajorTickForHorizSlider( Graphics g, Rectangle tickBounds, int x ) {
  421.     g.setColor( slider.isEnabled() ? OrganicLookAndFeel.getBlack() : darkShadowColor );
  422.     g.fillRect( x, 0 , 2, 2 );
  423.     }
  424.  
  425.     protected void paintMinorTickForVertSlider( Graphics g, Rectangle tickBounds, int y ) {
  426.     g.setColor( slider.getForeground()  );
  427.     g.fillRect( 0, y , 2, 2 );
  428.     }
  429.  
  430.     protected void paintMajorTickForVertSlider( Graphics g, Rectangle tickBounds, int y ) {
  431.     g.setColor( slider.isEnabled() ? OrganicLookAndFeel.getBlack() : darkShadowColor );
  432.     g.fillRect( 0, y , 2, 2 );
  433.     }
  434. }
  435.